<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Handshaking</title>
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../index.html" title="Chapter 1. Boost.Beast">
<link rel="up" href="../using_websocket.html" title="WebSocket">
<link rel="prev" href="establishing_connections.html" title="Connecting">
<link rel="next" href="decorator.html" title="Decorator">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="establishing_connections.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../using_websocket.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="decorator.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="beast.using_websocket.handshaking"></a><a class="link" href="handshaking.html" title="Handshaking">Handshaking</a>
</h3></div></div></div>
<h5>
<a name="beast.using_websocket.handshaking.h0"></a>
        <span class="phrase"><a name="beast.using_websocket.handshaking.client_role"></a></span><a class="link" href="handshaking.html#beast.using_websocket.handshaking.client_role">Client
        Role</a>
      </h5>
<p>
        A WebSocket session begins when a client sends the HTTP/1.1 <a href="https://tools.ietf.org/html/rfc7230#section-6.7" target="_top">Upgrade</a>
        request for <a href="https://tools.ietf.org/html/rfc6455#section-1.3" target="_top">WebSocket</a>
        on an established connection, and the server sends an appropriate response
        indicating that the request was accepted and that the connection has been
        upgraded. The Upgrade request must include the <a href="https://tools.ietf.org/html/rfc7230#section-5.4" target="_top">Host</a>
        field, and the <a href="https://tools.ietf.org/html/rfc7230#section-5.3" target="_top">target</a>
        of the resource to request. A typical HTTP Upgrade request created and sent
        by the implementation will look like this:
      </p>
<div class="table">
<a name="beast.using_websocket.handshaking.websocket_http_upgrade_request"></a><p class="title"><b>Table 1.30. WebSocket HTTP Upgrade Request</b></p>
<div class="table-contents"><table class="table" summary="WebSocket HTTP Upgrade Request">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
                <p>
                  Wire Format
                </p>
              </th>
<th>
                <p>
                  Description
                </p>
              </th>
</tr></thead>
<tbody><tr>
<td>
<pre class="programlisting"><span class="identifier">GET</span> <span class="special">/</span> <span class="identifier">HTTP</span><span class="special">/</span><span class="number">1.1</span>
<span class="identifier">Host</span><span class="special">:</span> <span class="identifier">www</span><span class="special">.</span><span class="identifier">example</span><span class="special">.</span><span class="identifier">com</span>
<span class="identifier">Upgrade</span><span class="special">:</span> <span class="identifier">websocket</span>
<span class="identifier">Connection</span><span class="special">:</span> <span class="identifier">upgrade</span>
<span class="identifier">Sec</span><span class="special">-</span><span class="identifier">WebSocket</span><span class="special">-</span><span class="identifier">Key</span><span class="special">:</span> <span class="number">2</span><span class="identifier">pGeTR0DsE4dfZs2pH</span><span class="special">+</span><span class="number">8</span><span class="identifier">MA</span><span class="special">==</span>
<span class="identifier">Sec</span><span class="special">-</span><span class="identifier">WebSocket</span><span class="special">-</span><span class="identifier">Version</span><span class="special">:</span> <span class="number">13</span>
<span class="identifier">User</span><span class="special">-</span><span class="identifier">Agent</span><span class="special">:</span> <span class="identifier">Boost</span><span class="special">.</span><span class="identifier">Beast</span><span class="special">/</span><span class="number">216</span>
</pre>
              </td>
<td>
                <p>
                  The host and target parameters become part of the Host field and
                  request-target in the resulting HTTP request. The key is generated
                  by the implementation. Callers who wish to add, modify, or inspect
                  fields may set the <span class="emphasis"><em>decorator</em></span> option on the
                  stream (described later).
                </p>
              </td>
</tr></tbody>
</table></div>
</div>
<br class="table-break"><p>
        The <a class="link" href="../ref/boost__beast__websocket__stream.html" title="websocket::stream"><code class="computeroutput"><span class="identifier">websocket</span><span class="special">::</span><span class="identifier">stream</span></code></a> member functions <a class="link" href="../ref/boost__beast__websocket__stream/handshake.html" title="websocket::stream::handshake"><code class="computeroutput"><span class="identifier">handshake</span></code></a> and <a class="link" href="../ref/boost__beast__websocket__stream/async_handshake.html" title="websocket::stream::async_handshake"><code class="computeroutput"><span class="identifier">async_handshake</span></code></a> are used to send
        the request with the required host and target strings. This code connects
        to the IP address returned from a hostname lookup, then performs the WebSocket
        handshake in the client role.
      </p>
<pre class="programlisting"><span class="identifier">stream</span><span class="special">&lt;</span><span class="identifier">tcp_stream</span><span class="special">&gt;</span> <span class="identifier">ws</span><span class="special">(</span><span class="identifier">ioc</span><span class="special">);</span>
<span class="identifier">net</span><span class="special">::</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span> <span class="identifier">resolver</span><span class="special">(</span><span class="identifier">ioc</span><span class="special">);</span>
<span class="identifier">get_lowest_layer</span><span class="special">(</span><span class="identifier">ws</span><span class="special">).</span><span class="identifier">connect</span><span class="special">(</span><span class="identifier">resolver</span><span class="special">.</span><span class="identifier">resolve</span><span class="special">(</span><span class="string">"www.example.com"</span><span class="special">,</span> <span class="string">"ws"</span><span class="special">));</span>

<span class="comment">// Do the websocket handshake in the client role, on the connected stream.</span>
<span class="comment">// The implementation only uses the Host parameter to set the HTTP "Host" field,</span>
<span class="comment">// it does not perform any DNS lookup. That must be done first, as shown above.</span>

<span class="identifier">ws</span><span class="special">.</span><span class="identifier">handshake</span><span class="special">(</span>
    <span class="string">"www.example.com"</span><span class="special">,</span>  <span class="comment">// The Host field</span>
    <span class="string">"/"</span>                 <span class="comment">// The request-target</span>
<span class="special">);</span>
</pre>
<p>
        When a client receives an HTTP Upgrade response from the server indicating
        a successful upgrade, the caller may wish to perform additional validation
        on the received HTTP response message. For example, to check that the response
        to a basic authentication challenge is valid. To achieve this, overloads
        of the handshake member function allow the caller to store the received HTTP
        message in an output reference argument of type <a class="link" href="../ref/boost__beast__websocket__response_type.html" title="websocket::response_type"><code class="computeroutput"><span class="identifier">response_type</span></code></a> as follows:
      </p>
<pre class="programlisting"><span class="comment">// This variable will receive the HTTP response from the server</span>
<span class="identifier">response_type</span> <span class="identifier">res</span><span class="special">;</span>

<span class="comment">// Perform the websocket handshake in the client role.</span>
<span class="comment">// On success, `res` will hold the complete HTTP response received.</span>

<span class="identifier">ws</span><span class="special">.</span><span class="identifier">handshake</span><span class="special">(</span>
    <span class="identifier">res</span><span class="special">,</span>                <span class="comment">// Receives the HTTP response</span>
    <span class="string">"www.example.com"</span><span class="special">,</span>  <span class="comment">// The Host field</span>
    <span class="string">"/"</span>                 <span class="comment">// The request-target</span>
<span class="special">);</span>
</pre>
<h5>
<a name="beast.using_websocket.handshaking.h1"></a>
        <span class="phrase"><a name="beast.using_websocket.handshaking.server_role"></a></span><a class="link" href="handshaking.html#beast.using_websocket.handshaking.server_role">Server
        Role</a>
      </h5>
<p>
        For servers accepting incoming connections, the <a class="link" href="../ref/boost__beast__websocket__stream.html" title="websocket::stream"><code class="computeroutput"><span class="identifier">websocket</span><span class="special">::</span><span class="identifier">stream</span></code></a> can read the incoming upgrade
        request and automatically reply. If the handshake meets the requirements,
        the stream sends back the upgrade response with a <a href="https://tools.ietf.org/html/rfc6455#section-4.2.2" target="_top"><span class="emphasis"><em>101
        Switching Protocols</em></span></a> status code. If the handshake does
        not meet the requirements, or falls outside the range of allowed parameters
        specified by stream options set previously by the caller, the stream sends
        back an HTTP response with a status code indicating an error. Depending on
        the keep alive setting, the connection may remain open for a subsequent handshake
        attempt. A typical HTTP Upgrade response created and sent by the implementation
        upon receiving an upgrade request handshake will look like this:
      </p>
<div class="table">
<a name="beast.using_websocket.handshaking.websocket_upgrade_http_response"></a><p class="title"><b>Table 1.31. WebSocket Upgrade HTTP Response</b></p>
<div class="table-contents"><table class="table" summary="WebSocket Upgrade HTTP Response">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
                <p>
                  Wire Format
                </p>
              </th>
<th>
                <p>
                  Description
                </p>
              </th>
</tr></thead>
<tbody><tr>
<td>
<pre class="programlisting"><span class="identifier">HTTP</span><span class="special">/</span><span class="number">1.1</span> <span class="number">101</span> <span class="identifier">Switching</span> <span class="identifier">Protocols</span>
<span class="identifier">Upgrade</span><span class="special">:</span> <span class="identifier">websocket</span>
<span class="identifier">Connection</span><span class="special">:</span> <span class="identifier">upgrade</span>
<span class="identifier">Sec</span><span class="special">-</span><span class="identifier">WebSocket</span><span class="special">-</span><span class="identifier">Accept</span><span class="special">:</span> <span class="identifier">s3pPLMBiTxaQ9kYGzzhZRbK</span><span class="special">+</span><span class="identifier">xOo</span><span class="special">=</span>
<span class="identifier">Server</span><span class="special">:</span> <span class="identifier">Boost</span><span class="special">.</span><span class="identifier">Beast</span>
</pre>
              </td>
<td>
                <p>
                  The <a href="https://tools.ietf.org/html/rfc6455#section-11.3.3" target="_top"><span class="emphasis"><em>Sec-WebSocket-Accept</em></span></a>
                  field value is generated from the request in a fashion specified
                  by the WebSocket protocol.
                </p>
              </td>
</tr></tbody>
</table></div>
</div>
<br class="table-break"><p>
        The <a class="link" href="../ref/boost__beast__websocket__stream.html" title="websocket::stream"><code class="computeroutput"><span class="identifier">stream</span></code></a> member functions <a class="link" href="../ref/boost__beast__websocket__stream/accept.html" title="websocket::stream::accept"><code class="computeroutput"><span class="identifier">accept</span></code></a> and <a class="link" href="../ref/boost__beast__websocket__stream/async_accept.html" title="websocket::stream::async_accept"><code class="computeroutput"><span class="identifier">async_accept</span></code></a> are used to read the
        WebSocket HTTP Upgrade request handshake from a stream already connected
        to an incoming peer, and then send the WebSocket HTTP Upgrade response, as
        shown:
      </p>
<pre class="programlisting"><span class="comment">// Perform the websocket handshake in the server role.</span>
<span class="comment">// The stream must already be connected to the peer.</span>

<span class="identifier">ws</span><span class="special">.</span><span class="identifier">accept</span><span class="special">();</span>
</pre>
<h5>
<a name="beast.using_websocket.handshaking.h2"></a>
        <span class="phrase"><a name="beast.using_websocket.handshaking.handshake_buffering"></a></span><a class="link" href="handshaking.html#beast.using_websocket.handshaking.handshake_buffering">Handshake
        Buffering</a>
      </h5>
<p>
        It is possible for servers to read data from the stream and decide later
        that the buffered bytes should be interpreted as a WebSocket upgrade request.
        To address this usage, overloads of <a class="link" href="../ref/boost__beast__websocket__stream/accept.html" title="websocket::stream::accept"><code class="computeroutput"><span class="identifier">accept</span></code></a> and <a class="link" href="../ref/boost__beast__websocket__stream/async_accept.html" title="websocket::stream::async_accept"><code class="computeroutput"><span class="identifier">async_accept</span></code></a> which accept an additional
        buffer sequence parameter are provided.
      </p>
<p>
        In this example, the server reads the initial HTTP request header into a
        dynamic buffer, then later uses the buffered data to attempt a websocket
        upgrade.
      </p>
<pre class="programlisting"><span class="comment">// This buffer will hold the HTTP request as raw characters</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">s</span><span class="special">;</span>

<span class="comment">// Read into our buffer until we reach the end of the HTTP request.</span>
<span class="comment">// No parsing takes place here, we are just accumulating data.</span>

<span class="identifier">net</span><span class="special">::</span><span class="identifier">read_until</span><span class="special">(</span><span class="identifier">sock</span><span class="special">,</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">dynamic_buffer</span><span class="special">(</span><span class="identifier">s</span><span class="special">),</span> <span class="string">"\r\n\r\n"</span><span class="special">);</span>

<span class="comment">// Now accept the connection, using the buffered data.</span>
<span class="identifier">ws</span><span class="special">.</span><span class="identifier">accept</span><span class="special">(</span><span class="identifier">net</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">s</span><span class="special">));</span>
</pre>
<h5>
<a name="beast.using_websocket.handshaking.h3"></a>
        <span class="phrase"><a name="beast.using_websocket.handshaking.inspecting_http_requests"></a></span><a class="link" href="handshaking.html#beast.using_websocket.handshaking.inspecting_http_requests">Inspecting
        HTTP Requests</a>
      </h5>
<p>
        When implementing an HTTP server that also supports WebSocket, the server
        usually reads the HTTP request from the client. To detect when the incoming
        HTTP request is a WebSocket Upgrade request, the function <a class="link" href="../ref/boost__beast__websocket__is_upgrade.html" title="websocket::is_upgrade"><code class="computeroutput"><span class="identifier">is_upgrade</span></code></a> may be used.
      </p>
<p>
        Once the caller determines that the HTTP request is a WebSocket Upgrade,
        additional overloads of <a class="link" href="../ref/boost__beast__websocket__stream/accept.html" title="websocket::stream::accept"><code class="computeroutput"><span class="identifier">accept</span></code></a> and <a class="link" href="../ref/boost__beast__websocket__stream/async_accept.html" title="websocket::stream::async_accept"><code class="computeroutput"><span class="identifier">async_accept</span></code></a> are provided which
        receive the entire HTTP request header as an object to perform the handshake.
        By reading the request manually, the program can handle normal HTTP requests
        as well as upgrades. The program may also enforce policies based on the HTTP
        fields, such as Basic Authentication. In this example, the request is first
        read in using the HTTP algorithms, and then passed to a newly constructed
        stream:
      </p>
<pre class="programlisting"><span class="comment">// This buffer is required for reading HTTP messages</span>
<span class="identifier">flat_buffer</span> <span class="identifier">buffer</span><span class="special">;</span>

<span class="comment">// Read the HTTP request ourselves</span>
<span class="identifier">http</span><span class="special">::</span><span class="identifier">request</span><span class="special">&lt;</span><span class="identifier">http</span><span class="special">::</span><span class="identifier">string_body</span><span class="special">&gt;</span> <span class="identifier">req</span><span class="special">;</span>
<span class="identifier">http</span><span class="special">::</span><span class="identifier">read</span><span class="special">(</span><span class="identifier">sock</span><span class="special">,</span> <span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">req</span><span class="special">);</span>

<span class="comment">// See if its a WebSocket upgrade request</span>
<span class="keyword">if</span><span class="special">(</span><span class="identifier">websocket</span><span class="special">::</span><span class="identifier">is_upgrade</span><span class="special">(</span><span class="identifier">req</span><span class="special">))</span>
<span class="special">{</span>
    <span class="comment">// Construct the stream, transferring ownership of the socket</span>
    <span class="identifier">stream</span><span class="special">&lt;</span><span class="identifier">tcp_stream</span><span class="special">&gt;</span> <span class="identifier">ws</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">sock</span><span class="special">));</span>

    <span class="comment">// Clients SHOULD NOT begin sending WebSocket</span>
    <span class="comment">// frames until the server has provided a response.</span>
    <span class="identifier">BOOST_ASSERT</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>

    <span class="comment">// Accept the upgrade request</span>
    <span class="identifier">ws</span><span class="special">.</span><span class="identifier">accept</span><span class="special">(</span><span class="identifier">req</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">else</span>
<span class="special">{</span>
    <span class="comment">// Its not a WebSocket upgrade, so</span>
    <span class="comment">// handle it like a normal HTTP request.</span>
<span class="special">}</span>
</pre>
<h5>
<a name="beast.using_websocket.handshaking.h4"></a>
        <span class="phrase"><a name="beast.using_websocket.handshaking.subprotocols"></a></span><a class="link" href="handshaking.html#beast.using_websocket.handshaking.subprotocols">Subprotocols</a>
      </h5>
<p>
        The WebSocket protocol understands the concept of subprotocols. If the client
        is requesting one of a set of subprotocols it will set the header <a href="https://tools.ietf.org/html/rfc6455#section-11.3.4" target="_top">Sec-WebSocket-Protocol</a>
        in the initial WebSocket Upgrade HTTP request. It is up to the server to
        parse the header and select one of the protocols to accept. The server indicates
        the selected protocol by setting the <a href="https://tools.ietf.org/html/rfc6455#section-11.3.4" target="_top">Sec-WebSocket-Protocol</a>
        header in the accept header.
      </p>
<p>
        This is accomplished with a <a class="link" href="../ref/boost__beast__websocket__stream_base__decorator.html" title="websocket::stream_base::decorator"><code class="computeroutput"><span class="identifier">decorator</span></code></a>.
      </p>
<p>
        The code that follows demonstrates how a server reads an HTTP request, identifies
        it as a WebSocket Upgrade, and then checks for a preferred matching subprotocol
        before performing the WebSocket handshake:
      </p>
<pre class="programlisting"><span class="comment">// a function to select the most preferred protocol from a comma-separated list</span>
<span class="keyword">auto</span> <span class="identifier">select_protocol</span> <span class="special">=</span> <span class="special">[](</span><span class="identifier">string_view</span> <span class="identifier">offered_tokens</span><span class="special">)</span> <span class="special">-&gt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span>
<span class="special">{</span>
    <span class="comment">// tokenize the Sec-Websocket-Protocol header offered by the client</span>
    <span class="identifier">http</span><span class="special">::</span><span class="identifier">token_list</span> <span class="identifier">offered</span><span class="special">(</span> <span class="identifier">offered_tokens</span> <span class="special">);</span>

    <span class="comment">// an array of protocols supported by this server</span>
    <span class="comment">// in descending order of preference</span>
    <span class="keyword">static</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="identifier">string_view</span><span class="special">,</span> <span class="number">3</span><span class="special">&gt;</span>
        <span class="identifier">supported</span> <span class="special">=</span> <span class="special">{</span>
        <span class="string">"v3.my.chat"</span><span class="special">,</span>
        <span class="string">"v2.my.chat"</span><span class="special">,</span>
        <span class="string">"v1.my.chat"</span>
    <span class="special">};</span>

    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">result</span><span class="special">;</span>

    <span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span> <span class="identifier">proto</span> <span class="special">:</span> <span class="identifier">supported</span><span class="special">)</span>
    <span class="special">{</span>
        <span class="keyword">auto</span> <span class="identifier">iter</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">find</span><span class="special">(</span><span class="identifier">offered</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">offered</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">proto</span><span class="special">);</span>
        <span class="keyword">if</span> <span class="special">(</span><span class="identifier">iter</span> <span class="special">!=</span> <span class="identifier">offered</span><span class="special">.</span><span class="identifier">end</span><span class="special">())</span>
        <span class="special">{</span>
            <span class="comment">// we found a supported protocol in the list offered by the client</span>
            <span class="identifier">result</span><span class="special">.</span><span class="identifier">assign</span><span class="special">(</span><span class="identifier">proto</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">proto</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
            <span class="keyword">break</span><span class="special">;</span>
        <span class="special">}</span>
    <span class="special">}</span>

    <span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span>
<span class="special">};</span>


<span class="comment">// This buffer is required for reading HTTP messages</span>
<span class="identifier">flat_buffer</span> <span class="identifier">buffer</span><span class="special">;</span>

<span class="comment">// Read the HTTP request ourselves</span>
<span class="identifier">http</span><span class="special">::</span><span class="identifier">request</span><span class="special">&lt;</span><span class="identifier">http</span><span class="special">::</span><span class="identifier">string_body</span><span class="special">&gt;</span> <span class="identifier">req</span><span class="special">;</span>
<span class="identifier">http</span><span class="special">::</span><span class="identifier">read</span><span class="special">(</span><span class="identifier">sock</span><span class="special">,</span> <span class="identifier">buffer</span><span class="special">,</span> <span class="identifier">req</span><span class="special">);</span>

<span class="comment">// See if it's a WebSocket upgrade request</span>
<span class="keyword">if</span><span class="special">(</span><span class="identifier">websocket</span><span class="special">::</span><span class="identifier">is_upgrade</span><span class="special">(</span><span class="identifier">req</span><span class="special">))</span>
<span class="special">{</span>
    <span class="comment">// we store the selected protocol in a std::string here because</span>
    <span class="comment">// we intend to capture it in the decorator's lambda below</span>
    <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">protocol</span> <span class="special">=</span>
        <span class="identifier">select_protocol</span><span class="special">(</span>
            <span class="identifier">req</span><span class="special">[</span><span class="identifier">http</span><span class="special">::</span><span class="identifier">field</span><span class="special">::</span><span class="identifier">sec_websocket_protocol</span><span class="special">]);</span>

    <span class="keyword">if</span> <span class="special">(</span><span class="identifier">protocol</span><span class="special">.</span><span class="identifier">empty</span><span class="special">())</span>
    <span class="special">{</span>
        <span class="comment">// none of our supported protocols were offered</span>
        <span class="identifier">http</span><span class="special">::</span><span class="identifier">response</span><span class="special">&lt;</span><span class="identifier">http</span><span class="special">::</span><span class="identifier">string_body</span><span class="special">&gt;</span> <span class="identifier">res</span><span class="special">;</span>
        <span class="identifier">res</span><span class="special">.</span><span class="identifier">result</span><span class="special">(</span><span class="identifier">http</span><span class="special">::</span><span class="identifier">status</span><span class="special">::</span><span class="identifier">bad_request</span><span class="special">);</span>
        <span class="identifier">res</span><span class="special">.</span><span class="identifier">body</span><span class="special">()</span> <span class="special">=</span> <span class="string">"No valid sub-protocol was offered."</span>
                      <span class="string">" This server implements"</span>
                      <span class="string">" v3.my.chat,"</span>
                      <span class="string">" v2.my.chat"</span>
                      <span class="string">" and v1.my.chat"</span><span class="special">;</span>
        <span class="identifier">http</span><span class="special">::</span><span class="identifier">write</span><span class="special">(</span><span class="identifier">sock</span><span class="special">,</span> <span class="identifier">res</span><span class="special">);</span>
    <span class="special">}</span>
    <span class="keyword">else</span>
    <span class="special">{</span>
        <span class="comment">// Construct the stream, transferring ownership of the socket</span>
        <span class="identifier">stream</span><span class="special">&lt;</span><span class="identifier">tcp_stream</span><span class="special">&gt;</span> <span class="identifier">ws</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">sock</span><span class="special">));</span>

        <span class="identifier">ws</span><span class="special">.</span><span class="identifier">set_option</span><span class="special">(</span>
            <span class="identifier">stream_base</span><span class="special">::</span><span class="identifier">decorator</span><span class="special">(</span>
                <span class="special">[</span><span class="identifier">protocol</span><span class="special">](</span><span class="identifier">http</span><span class="special">::</span><span class="identifier">response_header</span><span class="special">&lt;&gt;</span> <span class="special">&amp;</span><span class="identifier">hdr</span><span class="special">)</span> <span class="special">{</span>
                    <span class="identifier">hdr</span><span class="special">.</span><span class="identifier">set</span><span class="special">(</span>
                        <span class="identifier">http</span><span class="special">::</span><span class="identifier">field</span><span class="special">::</span><span class="identifier">sec_websocket_protocol</span><span class="special">,</span>
                        <span class="identifier">protocol</span><span class="special">);</span>
                <span class="special">}));</span>

        <span class="comment">// Accept the upgrade request</span>
        <span class="identifier">ws</span><span class="special">.</span><span class="identifier">accept</span><span class="special">(</span><span class="identifier">req</span><span class="special">);</span>
    <span class="special">}</span>
<span class="special">}</span>
<span class="keyword">else</span>
<span class="special">{</span>
    <span class="comment">// Its not a WebSocket upgrade, so</span>
    <span class="comment">// handle it like a normal HTTP request.</span>
<span class="special">}</span>
</pre>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2016-2019 Vinnie
      Falco<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
      </p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="establishing_connections.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../using_websocket.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="decorator.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
